package com.geoai.uicore.custom.ui

import android.content.Context
import android.graphics.Typeface
import android.util.AttributeSet
import android.util.TypedValue
import android.view.LayoutInflater
import android.view.View
import android.widget.FrameLayout
import android.widget.ImageButton
import android.widget.SeekBar
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import com.blankj.utilcode.util.NumberUtils
import com.geoai.uicore.R

/**
 *
 * @desc 进度条
 *
 */

class GEOUISeekbar : FrameLayout {

    private var listener: OnSeekBarAdvancedListener? = null
    private var isShowRange: Boolean = false
    private var max: Double = 10.0
    private var step: Double = 0.5
    private var min: Double = 0.0
    private lateinit var seekBar: SeekBar
    private lateinit var btnLeft: ImageButton
    private lateinit var btnRight: ImageButton
    private lateinit var tvTextTop: TextView
    private lateinit var tvItemName: TextView
    private lateinit var tvMin: TextView
    private lateinit var tvMax: TextView
    private lateinit var tvUnit: TextView
    private var firstSetMax: Boolean = true
    private var firstSetMin: Boolean = true

    constructor(context: Context) : this(context, null)
    constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
        val view = LayoutInflater.from(context).inflate(R.layout.widget_seekbar_advanced2, this)
        initView(view)
        initListener()
        setShowRange(false)
    }

    private fun initView(view: View) {
        seekBar = view.findViewById(R.id.seekbar)
        btnLeft = view.findViewById(R.id.btn_minus)
        btnRight = view.findViewById(R.id.btn_add)
        tvTextTop = view.findViewById(R.id.tv_text_top)
        tvItemName = view.findViewById(R.id.tv_item_name)
        tvMin = view.findViewById(R.id.tv_min)
        tvMax = view.findViewById(R.id.tv_max)
        tvUnit = view.findViewById(R.id.tv_unit)
    }

    private fun initListener() {
        seekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
            override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
                listener?.onValueChanging(convert(progress))
                updateTopText()
            }

            override fun onStartTrackingTouch(seekBar: SeekBar) {
                if (listener != null) {
                    tvMin.text = listener!!.onTextFormat(min)
                    tvMax.text = listener!!.onTextFormat(max)
                }
                setShowRange(true)
            }

            override fun onStopTrackingTouch(seekBar: SeekBar) {
                setShowRange(false)
                listener?.onValueChanged(convert(this@GEOUISeekbar.seekBar.progress))
            }
        })

        btnLeft.setOnClickListener { onTrimClicked(-1) }
        btnRight.setOnClickListener { onTrimClicked(1) }
    }


    /**
     * 修改顶部进度显示
     * 根据进度修改view位置
     */
    private fun updateTopText() {
        // 获取约束布局参数
        val params = tvTextTop.layoutParams as ConstraintLayout.LayoutParams
        // 修改view横向约束百分比
        params.horizontalBias = if (getMax() - getMin() == 0.0) 0.5f else ((getValue() - getMin()) / (getMax() - getMin())).toFloat()

        val text = formatValue(getValue())
        tvTextTop.text = text
        tvTextTop.layoutParams = params
    }

    /**
     * 将进度百分比转换
     */
    fun formatValue(value: Double): String {
        return listener?.onTextFormat(value) ?: ""
    }

    /**
     * 显示范围
     */
    fun setShowRange(showRange: Boolean) {
        isShowRange = showRange

        if (showRange) {
            tvMin.visibility = View.VISIBLE
            tvMax.visibility = View.VISIBLE
            tvTextTop.typeface = Typeface.DEFAULT_BOLD
            tvTextTop.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16f)
            tvUnit.typeface = Typeface.DEFAULT_BOLD
            tvUnit.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16f)
        } else {
            tvMin.visibility = View.GONE
            tvMax.visibility = View.GONE
            tvTextTop.typeface = Typeface.DEFAULT
            tvTextTop.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14f)
            tvUnit.typeface = Typeface.DEFAULT
            tvUnit.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14f)
        }
    }

    /**
     * 使用按钮修改进度
     */
    fun onTrimClicked(diff: Int) {
        val oldProgress = seekBar.progress
        seekBar.incrementProgressBy(diff)
        val progress = seekBar.progress
        if (progress != oldProgress) {
            listener?.onValueChanged(getValue())
        }
    }

    fun setTopText(text: String) {
        tvTextTop.text = text
    }

    fun setItemName(text: String) {
        tvItemName.text = text
    }

    private fun convert(progress: Int): Double {
        return NumberUtils.format((min + progress * step), 1).toDouble()
    }

    fun getMax(): Double {
        return max
    }

    fun setMax(max: Double) {
        if (this.max != max && !firstSetMax) {
            listener?.onValueChanged(getValue())
        }
        firstSetMax = false
        this.max = max
        updateSeekBar()
        listener?.onTextFormat(this.max).let { tvMax.text = it }
    }

    fun getMin(): Double {
        return min
    }

    fun setMin(min: Double) {
        if (this.min != min && !firstSetMin) {
            listener?.onValueChanged(getValue())
        }
        firstSetMin = false
        this.min = min
        updateSeekBar()
        listener?.onTextFormat(this.min).let { tvMin.text = it }
    }

    fun getStep(): Double {
        return step
    }

    fun setStep(step: Double) {
        this.step = step
        updateSeekBar()
    }

    /**
     * 获取进度条进度百分比
     */
    fun getValue(): Double {
        return convert(seekBar.progress)
    }


    fun setValue(value: Double) {
        seekBar.progress = convertBack(value)
        updateTopText()
    }

    fun convertBack(value: Double): Int {
        return ((value - min) / step + 0.5).toInt()
    }

    private fun updateSeekBar() {
        if (step == 0.0) return
        seekBar.max = ((max - min) / step).toInt()
    }

    fun setUnitText(unitText: String) {
        tvUnit.text = unitText
    }

    fun setListener(listener: OnSeekBarAdvancedListener) {
        this.listener = listener
    }

    fun getListener(): OnSeekBarAdvancedListener? {
        return listener
    }

    override fun setEnabled(enabled: Boolean) {
        super.setEnabled(enabled)
        if (enabled) {
            seekBar.thumb =
                    this.resources.getDrawable(R.drawable.geosurvey_route_setting_seek_bar_thumb)
            seekBar.progressDrawable =
                    this.resources.getDrawable(R.drawable.geosurvey_route_setting_seek_bar_bg)
            btnLeft.setImageResource(R.drawable.ic_decreasing)
            btnRight.setImageResource(R.drawable.ic_incremental)
        } else {
            seekBar.thumb = this.resources.getDrawable(R.mipmap.ic_slide_point_disable)
            seekBar.progressDrawable =
                    this.resources.getDrawable(R.drawable.geosurvey_route_setting_seek_bar_bg_disable)
            btnLeft.setImageResource(R.drawable.ic_decreasing_disable)
            btnRight.setImageResource(R.drawable.ic_incremental_disable)
        }
        seekBar.isEnabled = enabled
        btnLeft.isEnabled = enabled
        btnRight.isEnabled = enabled
    }

    /**
     * SeekBar监听
     */
    interface OnSeekBarAdvancedListener {
        /** 拖动进度条 */
        fun onValueChanging(value: Double)

        /** 停止拖动或点击按钮修改进度 */
        fun onValueChanged(value: Double)

        fun onTextFormat(value: Double): String
    }
}